package public

import (
	"fmt"
	"sync/atomic"
	"time"
)

type FlowCountService struct {
	AppID         string        //应用ID
	Interval      time.Duration //采集频率
	TotalCount    int64         //当前总共请求数
	QPS           int64         //QPS
	LastTimeStamp int64         //上次unix时间戳
	TickerCount   int64         //当前流量. 定时时间内流量数
}

// appID 应用id, interval采集频率
func NewFlowCountService(appID string, interval time.Duration) (*FlowCountService, error) {
	reqCounter := &FlowCountService{
		AppID:         appID,
		Interval:      interval,
		QPS:           0,
		LastTimeStamp: 0,
		TickerCount:   0,
	}
	go func() {
		defer func() {
			if err := recover(); err != nil {
				fmt.Println(err)
			}
		}()
		ticker := time.NewTicker(interval) //定时器
		for range ticker.C {
			//原子操作
			tickerCount := atomic.SwapInt64(&reqCounter.TickerCount, 0) // 当前流量num

			now := time.Now()
			// 计算窗口内的秒数（使用精确时间）
			TimeStamp := now.Sub(time.Unix(reqCounter.LastTimeStamp, 0)).Seconds()
			if TimeStamp > 0 {
				// 使用原子操作更新 QPS 和 TotalCount
				atomic.AddInt64(&reqCounter.TotalCount, tickerCount)
				atomic.StoreInt64(&reqCounter.QPS, int64(float64(tickerCount)/TimeStamp))
				reqCounter.LastTimeStamp = time.Now().Unix()
			}
		}
	}()
	return reqCounter, nil
}

func NewFlowCountService1(appID string, interval time.Duration) (*FlowCountService, error) {
	reqCounter := &FlowCountService{
		AppID:         appID,
		Interval:      interval,
		QPS:           0,
		LastTimeStamp: 0,
		TickerCount:   0,
	}
	go func() {
		defer func() {
			if err := recover(); err != nil {
				fmt.Println(err)
			}
		}()
		ticker := time.NewTicker(interval) //定时器
		for {
			<-ticker.C
			//原子操作
			tickerCount := atomic.LoadInt64(&reqCounter.TickerCount) // 当前流量num
			atomic.StoreInt64(&reqCounter.TickerCount, 0)
			nowTimeStamp := time.Now().Unix()
			if reqCounter.LastTimeStamp == 0 {
				reqCounter.LastTimeStamp = time.Now().Unix()
				continue
			}
			if nowTimeStamp > reqCounter.LastTimeStamp { // 刷新qps、TotalCount、LastTimeStamp
				reqCounter.QPS = tickerCount / (nowTimeStamp - reqCounter.LastTimeStamp)
				reqCounter.TotalCount = reqCounter.TotalCount + tickerCount
				reqCounter.LastTimeStamp = time.Now().Unix()
			}
		}
	}()
	return reqCounter, nil
}

// 原子增加
func (f *FlowCountService) Increase() {
	go func() {
		defer func() {
			if err := recover(); err != nil {
				fmt.Println(err)
			}
		}()
		atomic.AddInt64(&f.TickerCount, 1)
	}()
}
